/*
  ScioSense_ENS210.h - Library for the ENS210 relative humidity and temperature sensor with I2C interface from ScioSense
  2020 Apr 06	v3	Christoph Friese	Changed nomenclature to ScioSense as product shifted from ams
  2018 Aug 28	v2	Christoph Friese	Adjusted I2C communication 
  2017 Aug 01	v1	Maarten Pennings	Created
*/

#include "ens210_iic.h"


uint8_t I2C1_Buffer_Tx[10], I2C1_Buffer_Rx[10] ;
uint8_t Tx_Idx, Rx_Idx, Tx_Data_Cnt;

bool Ens210_Crc_Flag;

static u32 wTempData, wRH_Data;
    static u32 wTempCRC, wRH_CRC;
static uint32_t crc7( uint32_t val ) ;
unsigned int cal_crc(u32 ptr, unsigned char len);

// Compute the CRC-7 of 'val' (should only have 17 bits)
// https://en.wikipedia.org/wiki/Cyclic_redundancy_check#Computation
static uint32_t crc7( uint32_t val ) 
{
	// Setup polynomial
	uint32_t pol = CRC7POLY;
    uint32_t bit;
	// Align polynomial with data
	pol = pol << (DATA7WIDTH-CRC7WIDTH-1);
	// Loop variable (indicates which bit to test, start with highest)
    bit = DATA7MSB;
	// Make room for CRC value
	val = val << CRC7WIDTH;
	bit = bit << CRC7WIDTH;
	pol = pol << CRC7WIDTH;
	// Insert initial vector
	val |= CRC7IVEC;
	// Apply division until all bits done
	while( bit & (DATA7MASK<<CRC7WIDTH) ) {
		if( bit & val ) val ^= pol;
		bit >>= 1;
		pol >>= 1;
	}
	return val;
}

/**
 * init i2c to fake ENS210 sensor 
*/
void Ens210_init( void  )
{
    I2C_InitTypeDef  I2C_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;

    I2C_DeInit(I2C1);

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    /*!< GPIO configuration */  
    /*!< Configure sEE_I2C pins: SCL */
    GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN | I2C_SDA_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
    // GPIO_Init(I2C_SCL_GPIO_PORT, &GPIO_InitStructure);
    // /*!< Configure sEE_I2C pins: SDA */
    // GPIO_InitStructure.GPIO_Pin = I2C_SDA_PIN;
    // GPIO_Init(I2C_SDA_GPIO_PORT, &GPIO_InitStructure); 
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    /* I2C1 configuration ------------------------------------------------------*/
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;//模式
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1 = I2C_SLAVE_ADDRESS7<<1;//这个就是作为从机的地址，一定要配置正确
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//7位的地址
    I2C_InitStructure.I2C_ClockSpeed = ClockSpeed;
    I2C_Init(I2C1, &I2C_InitStructure);

     /* Configure and enable I2Cx event interrupt -------------------------------*/
    NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
 
    /* Configure and enable I2C1 error interrupt -------------------------------*/
    NVIC_InitStructure.NVIC_IRQChannel = I2C1_ER_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
    NVIC_Init(&NVIC_InitStructure);

    /* Enable I2C1 event and buffer interrupts */
    I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, ENABLE);
    
    /* Enable I2C1 Error interrupts */
    I2C_ITConfig(I2C1, I2C_IT_ERR, ENABLE);

    I2C1_Buffer_Tx[0] = 0xb7;
    I2C1_Buffer_Tx[1] = 0x48;
    I2C1_Buffer_Tx[2] = 0x61;
    I2C1_Buffer_Tx[3] = 0xdf;
    I2C1_Buffer_Tx[4] = 0x80;
    I2C1_Buffer_Tx[5] = 0x91;
    wTempData   = 0x004449;
    wRH_Data    = 0x0000;
    Ens210_Crc_Flag = TRUE;

}


void I2C1_EV_IRQHandler(void) //事件中断处理函数 
{ 
    switch (I2C_GetLastEvent(I2C1)) //获取i2c1的中断事件 
    { 
    /* Slave Transmitter ---------------------------------------------------*/  
    case I2C_EVENT_SLAVE_BYTE_TRANSMITTED: 
    /* 这个和下面那个都是从发送模式下发送数据的，具体两个的区别我也不是很明白，感觉就是移位寄存器空与非  空的区别,准备好数据发送吧 */ 
        I2C_SendData(I2C1, I2C1_Buffer_Tx[Tx_Idx++]);
    break; 
    case I2C_EVENT_SLAVE_BYTE_TRANSMITTING:             /* EV3 */    
    /* Transmit I2C1 data */
        I2C_SendData(I2C1, I2C1_Buffer_Tx[Tx_Idx++]); 
    break; 
    /* Slave Receiver ------------------------------------------------------*/ 
    case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:     /* EV1 */ 
    /* 地址匹配中断，不管从发送和接收都要匹配地址，如下图244、243发送地址之后都会响应EV1 */ 
    break; 
    case I2C_EVENT_SLAVE_BYTE_RECEIVED:                /* EV2 */ 
    /* Store I2C1 received data */ 
    /* 这个中断就是响应EV2中断，如下图244，每次主机发送完一个数据就会产生一个EV2的中断 */ 
        I2C1_Buffer_Rx[Rx_Idx++] = I2C_ReceiveData(I2C1);
    /* 把接收到的中断填充到数组中 */ 
    /* 注意：地址不会填充进来的 */
    break; 
    case I2C_EVENT_SLAVE_STOP_DETECTED:                /* EV4 */
    /* Clear I2C1 STOPF flag */ 
    /* 这个就是正常停止的时候产生的一个停止信号 */ 
        I2C_Cmd( I2C1, ENABLE ); 
    /* 我也不清楚这个为什么要这样，如果接收完一串数据之后，不响应主机的情况可以 关闭i2c，然后在处理完数据后再  从新配置i2c，记得是从新配置 */ 
        Rx_Idx = 0; 
        // i2c_event = EVENT_OPCOD_NOTYET_READ; 
    break; 
    default: 
    break;    
    } 
} 
 
void I2C1_ER_IRQHandler(void) 
{ 
    /* Check on I2C1 AF flag and clear it */ 
    if (I2C_GetITStatus(I2C1, I2C_IT_AF)) 
    { 
    /* 这个就是图243中最后那个没有应答的中断，也就是发送了一串数据后的中断，可以做清零工作 */  
    I2C_ClearITPendingBit(I2C1, I2C_IT_AF); 
    Tx_Idx = 0; 
    Ens210_Crc_Flag = TRUE;
    //   i2c_event = EVENT_OPCOD_NOTYET_READ; 
    } 
    /* Check on I2C1 AF flag and clear it */ 
    if (I2C_GetITStatus(I2C1, I2C_IT_BERR))   //这个就是起始和停止条件出错了
    { 
    I2C_ClearITPendingBit(I2C1, I2C_IT_BERR);
    }
 
 }
 
/**
 * 
 * 
*/
void Ens210_Fake_Data_Haldle( void )
{
    
    if(Ens210_Crc_Flag)/*  */
    {
        Tx_Data_Cnt ++;
        // if( 0x02 == Tx_Data_Cnt %4)
        // {
        //     wTempData ++;
        //     if(wTempData > 0x004949)
        //         wTempData = 0x004449;/*0 to 20 */
        // }
        if( 0x00 == Tx_Data_Cnt %4 )
        {
            wRH_Data += 4;
            if(wRH_Data > 0x00C800)
                wRH_Data = 0x000000;    /* 0 to 100 percent*/
        }
        /* calculate CRC */
        wTempCRC = crc7( (wTempData | 0x010000) & 0x1ffff );
        wRH_CRC  = crc7( (wRH_Data | 0x010000) & 0x1ffff );
        /* fill Tx buffer */

        I2C1_Buffer_Tx[0] = (u8)(wTempData & 0xff);
        I2C1_Buffer_Tx[1] = (u8)(wTempData>> 8);
        I2C1_Buffer_Tx[2] = (u8)( (wTempCRC<<1) | 0x01);    /* CRC为高7位，最低位为数据有效标识 */
        I2C1_Buffer_Tx[3] = (u8)(wRH_Data & 0xff);
        I2C1_Buffer_Tx[4] = (u8)(wRH_Data >> 8);
        I2C1_Buffer_Tx[5] = (u8)( (wRH_CRC<<1) | 0x01);

        Ens210_Crc_Flag = FALSE;
    }
}
